import uuid
from typing import Any

from fastapi import APIRouter, HTTPException
from sqlmodel import func, select

from app.api.deps import CurrentUser, SessionDep
from app.models.training_models import (
    TrainingSession,
    TrainingSessionCreate,
    TrainingSessionUpdate,
    TrainingSessionPublic,
    TrainingSessionsPublic,
    TrainingTurn,
    TrainingTurnCreate,
    TrainingTurnPublic,
    TrainingHistoryResponse,
    TrainingTurnsResponse,
)

router = APIRouter(prefix="/trainings", tags=["trainings"])


@router.get("/", response_model=TrainingSessionsPublic)
def read_training_sessions(
        session: SessionDep, current_user: CurrentUser, skip: int = 0, limit: int = 100
) -> Any:
    if current_user.is_superuser:
        count = session.exec(select(func.count()).select_from(TrainingSession)).one()
        items = session.exec(select(TrainingSession).offset(skip).limit(limit)).all()
    else:
        count = session.exec(
            select(func.count()).select_from(TrainingSession).where(TrainingSession.user_id == current_user.id)
        ).one()
        items = session.exec(
            select(TrainingSession)
            .where(TrainingSession.user_id == current_user.id)
            .offset(skip)
            .limit(limit)
        ).all()
    return TrainingSessionsPublic(data=items, count=count)


@router.get("/history", response_model=TrainingHistoryResponse)
def get_training_history(
        session: SessionDep,
        current_user: CurrentUser,
        skip: int = 0,
        limit: int = 100
) -> Any:
    """获取用户的培训历史记录"""
    if current_user.is_superuser:
        count = session.exec(select(func.count()).select_from(TrainingSession)).one()
        items = session.exec(
            select(TrainingSession)
            .order_by(TrainingSession.created_at.desc())
            .offset(skip)
            .limit(limit)
        ).all()
    else:
        count = session.exec(
            select(func.count())
            .select_from(TrainingSession)
            .where(TrainingSession.user_id == current_user.id)
        ).one()
        items = session.exec(
            select(TrainingSession)
            .where(TrainingSession.user_id == current_user.id)
            .order_by(TrainingSession.created_at.desc())
            .offset(skip)
            .limit(limit)
        ).all()
    return TrainingHistoryResponse(data=items, count=count)


@router.get("/{id}", response_model=TrainingSessionPublic)
def read_training_session(session: SessionDep, current_user: CurrentUser, id: uuid.UUID) -> Any:
    training = session.get(TrainingSession, id)
    if not training:
        raise HTTPException(status_code=404, detail="Training session not found")
    if not current_user.is_superuser and training.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    return training


@router.post("/", response_model=TrainingSessionPublic)
def create_training_session(
        *, session: SessionDep, current_user: CurrentUser, item_in: TrainingSessionCreate
) -> Any:
    training = TrainingSession.model_validate(item_in, update={"user_id": current_user.id})
    session.add(training)
    session.commit()
    session.refresh(training)
    return training


@router.put("/{id}", response_model=TrainingSessionPublic)
def update_training_session(
        *, session: SessionDep, current_user: CurrentUser, id: uuid.UUID, item_in: TrainingSessionUpdate
) -> Any:
    training = session.get(TrainingSession, id)
    if not training:
        raise HTTPException(status_code=404, detail="Training session not found")
    if training.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    update_dict = item_in.model_dump(exclude_unset=True)
    training.sqlmodel_update(update_dict)
    session.add(training)
    session.commit()
    session.refresh(training)
    return training


@router.delete("/{id}")
def delete_training_session(
        session: SessionDep, current_user: CurrentUser, id: uuid.UUID
) -> dict:
    training = session.get(TrainingSession, id)
    if not training:
        raise HTTPException(status_code=404, detail="Training session not found")
    if not current_user.is_superuser and training.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    session.delete(training)
    session.commit()
    return {"message": "Training session deleted successfully"}


@router.post("/turns", response_model=TrainingTurnPublic)
def create_training_turn(
        *, session: SessionDep, current_user: CurrentUser, item_in: TrainingTurnCreate
) -> Any:
    turn = TrainingTurn.model_validate(item_in)
    session.add(turn)
    session.commit()
    session.refresh(turn)
    return turn


@router.get("/turns/{session_id}", response_model=list[TrainingTurnPublic])
def read_turns_by_session(session: SessionDep, session_id: uuid.UUID) -> Any:
    turns = session.exec(
        select(TrainingTurn).where(TrainingTurn.session_id == session_id).order_by(TrainingTurn.turn_index)
    ).all()
    return turns


@router.get("/sessions/{session_id}/messages", response_model=TrainingTurnsResponse)
def get_session_messages(
        session: SessionDep,
        current_user: CurrentUser,
        session_id: uuid.UUID
) -> Any:
    """获取特定培训会话的所有消息"""
    # 首先检查会话是否存在且属于当前用户
    training = session.get(TrainingSession, session_id)
    if not training:
        raise HTTPException(status_code=404, detail="Training session not found")

    if not current_user.is_superuser and training.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")

    # 获取会话的所有消息
    turns = session.exec(
        select(TrainingTurn)
        .where(TrainingTurn.session_id == session_id)
        .order_by(TrainingTurn.turn_index)
    ).all()

    count = len(turns)
    return TrainingTurnsResponse(data=turns, count=count)